Load the Seurat object and CellTag clones
TBO_seurat<-readRDS("../data/07_2025_RPM_RPMA_TBO_CellTag_Seurat_wSigs_FA_dpt_final.rds")
TBO_seurat
An object of class Seurat
110982 features across 26618 samples within 2 assays
Active assay: RNA (55491 features, 0 variable features)
2 layers present: counts, data
1 other assay present: norm
2 dimensional reductions calculated: umap, fa
clones <- readRDS("../data/05_2025_RPM_RPMA_TBOAllo_CellTagClones_Onlyclones.rds")
clones
An object of class Seurat
110982 features across 5965 samples within 2 assays
Active assay: RNA (55491 features, 0 variable features)
2 layers present: counts, data
1 other assay present: norm
2 dimensional reductions calculated: umap, fa
Load organoid data as SingleCellExperiment
sce <- as.SingleCellExperiment(TBO_seurat, assay = "norm")
Warning :The `slot` argument of `GetAssayData()` is deprecated as of SeuratObject 5.0.0.
ℹ Please use the `layer` argument instead.
ℹ The deprecated feature was likely used in the Seurat package.
Please report the issue at <]8;;https://github.com/satijalab/seurat/issueshttps://github.com/satijalab/seurat/issues]8;;>.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_]8;;ide:run:warnings()warnings()]8;;` to see where this warning was generated.
phenotypes <- as.character(unique(sce@colData@listData$Pheno))
pheno_pairs_list <- combn(phenotypes, 2, simplify = FALSE)
Define color palettes
my_colors <- c(
"#E41A1C", # strong red
"#377EB8", # medium blue
"#4DAF4A", # green
"#984EA3", # purple
"#FF7F00", # orange
"#FFFF33", # yellow
"#A65628", # brown
"#e7298a", # pink
"#666666", # grey
"#66C2A5", # teal
"#FC8D62", # salmon
"#8DA0CB", # soft blue
"#E78AC3", # soft pink (different from 8)
"#A6D854", # light green (but yellowish tint, not green)
"#FFD92F", # lemon yellow
"#E5C494", # light brown
"#B3B3B3", # light grey
"#1B9E77", # deep teal
"#D95F02", # dark orange
"#7570B3", # strong purple
"#66A61E" # olive green (NOT same green as before)
)
Define function to plot violin plots by phenotype
Copied from 02_WT_RPM_Organoids_Allografts_notebook.Rmd
Needs SingleCellExperiment sce object and
pheno_pairs_list defined in the notebook.
plotVlnByPhen <- function(feature, yl=c(-0.1,0.3), focus=NA) {
if(!is.na(focus)) {
pheno_pairs_list <- pheno_pairs_list[sapply(pheno_pairs_list, function(x) focus %in% x)]
}
scater::plotColData(sce, x = "Pheno", y = feature, colour_by = "Pheno") +
scale_discrete_manual(aesthetics = c("colour", "fill"), values=pheno_col) +
theme(axis.title.y = element_text(size = 24), axis.text.y = element_text(size = 16),
axis.text.x = element_blank(), # rotate x-axis labels
plot.title = element_blank(), # remove plot title
legend.position = "none" # remove legend
) + labs(x = "", # custom x-axis title
y = "Signature score" # custom y-axis title
) + ylim(yl[1], yl[2]) +
geom_boxplot(fill=pheno_col, alpha=1/5, position = position_dodge(width = .2),
size=0.2, color="black", notch=TRUE, notchwidth=0.3, outlier.shape = 2, outlier.colour=NA) # +
# stat_summary(fun = mean,
# geom = "point",
# shape = 18,
# size = 2,
# color = "red",
# position = position_dodge(width = 0.5)) +
# ggpubr::stat_compare_means(method = "wilcox.test", label = "p.signif", size=4,
# vjust = 0.5,
# hide.ns = TRUE, comparisons = pheno_pairs_list)
}
Fig. 2e UMAP
DimPlot(TBO_seurat, group.by='Genotype', cols=c("darkorchid4","orange"),
pt.size = 0.1,
reduction='umap', label=FALSE, label.size=7, shuffle=TRUE) & NoAxes()

Fig. 2f (UMAP by Leiden cluster)
DimPlot(TBO_seurat, group.by='leiden_scVI_1.2',
cols=my_colors, reduction='umap', label=TRUE, label.size=5,
pt.size = 0.1) & NoAxes() +
theme(legend.position="none")

Idents(TBO_seurat) <- 'leiden_scVI_1.2'
x <- table(TBO_seurat@meta.data$Genotype,Idents(TBO_seurat))
proportions <- as.data.frame(100*prop.table(x, margin = 1))
colnames(proportions) <- c("Sample", "Cluster", "Frequency")
# ggpubr::ggbarplot(proportions, x="Sample", y="Frequency", fill = "Sample", group = "Sample",
# ylab = "Frequency (percent)", xlab="Phase", palette =c("indianred3","green3","royalblue4")) +
# theme_bw() + facet_wrap(facets = "Cluster", scales="free_y", ncol =4) +
# theme(axis.text.y = element_text(size=6)) + ggpubr::rotate_x_text(angle = 45)
Fig 2f
# Stacked
p <- ggplot(proportions, aes(fill=Cluster, y=Frequency, x=Sample)) +
geom_bar(position="stack", stat="identity")
p + scale_fill_manual(values=my_colors) + theme_bw() +
theme(axis.text.y = element_text(size=16),
axis.text.x = element_text(size=16, angle = 90, vjust = 0.5, hjust=1),
axis.title.x = element_text(size=16), axis.title.y = element_text(size=16),
legend.text = element_text(size=12), legend.title = element_blank()) +
labs(x = NULL, y = "Sample composition (%)")

Fig. 2h
UMAP colored by SCLC fate
# Define fate color vector and use to plot by cell state
pheno_col <- c("brown2","darkorchid4","dodgerblue","#66A61E","orange","turquoise4","turquoise")
DimPlot(TBO_seurat, group.by='Pheno', cols=pheno_col, reduction='umap', label=FALSE,
shuffle=TRUE, label.size=6) & NoAxes()

Fig. 2h (stacked barplot by Pheno)
Idents(TBO_seurat) <-'Pheno'
x <- table(TBO_seurat@meta.data$Genotype,Idents(TBO_seurat))
proportions <- as.data.frame(100*prop.table(x, margin = 1))
colnames(proportions)<-c("Cluster", "Sample", "Frequency")
p <- ggplot(proportions, aes(fill=Sample, y=Frequency, x=Cluster)) +
geom_bar(position="stack", stat="identity")
p + scale_fill_manual(values=pheno_col) + theme_bw() +
theme(axis.text.y = element_text(size=20),
axis.text.x=element_text(size=20, angle = 90, hjust = 1, vjust = 0.5),
axis.title.x = element_text(size=20), axis.title.y = element_text(size=20),
legend.text = element_text(size=20), legend.title = element_text(size=20)) +
labs(x = NULL)

Fig. 2i UMAP
NE score (correlation)
FeaturePlot(TBO_seurat, features = c("NE_spearman"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

Fig 2i (violin plots of NE score by SCLC fate)
plotVlnByPhen("NE_spearman", yl=c(-.7, .8))

Fig 2i (violin plots of NE score by genotype)
x <- scater::plotColData(sce, x = "Genotype", y = "NE_spearman", colour_by = "Genotype") +
scale_discrete_manual(aesthetics = c("colour", "fill"), values=c("darkorchid4","orange"))
x <- x + theme(axis.title.y = element_text(size = 24),axis.text.y = element_text(size = 16),
axis.text.x = element_blank(),
# plot.title = element_blank(),
legend.position = "none") + labs(x = "", y = "Signature score") + ylim(-1,1) +
geom_boxplot(fill=c("darkorchid4","orange"), alpha=1/5,
position = position_dodge(width = .2), size=0.2,
color="black", notch=TRUE, notchwidth=0.3, outlier.shape = 2, outlier.colour=NA)
## Perform wilcoxon rank-sum test for RPM vs RPMA on the NE score data (Fig. 3i) ##
x + stat_summary(fun = mean,
geom = "point",
shape = 18,
size = 2,
color = "red",
position = position_dodge(width = 0.9)) +
ggpubr::stat_compare_means(method = "wilcox.test",label = "p.signif",
hide.ns = TRUE,comparisons = list(c("RPM", "RPMA")))

Fig. 2j
Fig 2j (UMAP marker gene expression)
Equivalent color schemes:
*
viridis::scale_color_viridis(option="rocket", direction=-1)
*
scale_color_gradientn(colors=viridis::rocket(10, direction=-1))
# TF target gene scores in UMAP
FeaturePlot(TBO_seurat, features = c("ASCL1_Targets1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

FeaturePlot(TBO_seurat, features = c("NEUROD1_Targets1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

FeaturePlot(TBO_seurat, features = c("ATOH1_Targets1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

FeaturePlot(TBO_seurat, features = c("POU2F3_Targets1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

FeaturePlot(TBO_seurat, features = c("YAP_Activity1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

VlnPlots by genotype with wilcoxon rank sum tests
Fig. 2j (violin plots)
plotTFscoresVln <- function(score_name, yl=c(-.1, .32)) {
a <- VlnPlot(TBO_seurat,
features = c(score_name),
group.by = "Genotype",
cols = c("darkorchid4", "orange"),
pt.size = 0.01,
alpha = 0.05,
ncol = 1) +
theme(axis.title.y = element_text(size = 20),
axis.text.x = element_text(angle = 0, hjust = 0.5, size=20), # rotate x-axis labels
# plot.title = element_blank(), # remove plot title
legend.position = "none" # remove legend
) +
labs(x = "", # custom x-axis title
y = "Expression" # custom y-axis title
) + ylim(yl[1], yl[2]) +
stat_summary(fun = mean,
geom = "point",
shape = 18,
size = 2,
color = "red",
position = position_dodge(width = 0.9)) +
ggpubr::stat_compare_means(method = "wilcox.test", label = "p.signif", size=8,
hide.ns = TRUE, comparisons = list(c("RPM", "RPMA")))
# Add mean point and do wilcoxon rank sum test
return(a)
}
Fig 2j (insets)
plotTFscoresVln("ATOH1_Targets1")

plotTFscoresVln("ASCL1_Targets1", yl=c(-0.1, 0.8))

plotTFscoresVln("NEUROD1_Targets1")

plotTFscoresVln("POU2F3_Targets1")

plotTFscoresVln("YAP_Activity1", yl=c(-0.1, 1))

Fig. 2k (UMAP by cell type consensus signature)
FeaturePlot(TBO_seurat, features = c("NE_Consensus1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

FeaturePlot(TBO_seurat, features = c("Basal_Consensus1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

FeaturePlot(TBO_seurat, features = c("Tuft_Consensus1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

Fig. 2k (violin plots of consensus signatures by SCLC fate)
plotVlnByPhen("NE_Consensus1", yl=c(-0.5, 1.3))

plotVlnByPhen("Tuft_Consensus1", yl=c(-0.25, 1))

plotVlnByPhen("Basal_Consensus1", yl=c(-0.1, 1.1))

Fig 2l (violin plots of SCLC arhcetype scores by phenotype)
plotVlnByPhen("A_Archetype1", yl=c(-0.05, 0.27))

plotVlnByPhen("A2_Archetype1", yl=c(-0.05, 0.2))

plotVlnByPhen("N_Archetype1", yl=c(0, 0.3))

plotVlnByPhen("P_Archetype1", yl=c(0, 0.27))

Ext Data Fig 5c
plotStackedBarByGeno <- function(gene, lab) {
dat <- FetchData(TBO_seurat, vars = c(gene, "Genotype"))
dat <- dat %>%
mutate(Expression_Status = ifelse(dat[,gene] > 0.01, "Positive", "Negative"))
x <- table(dat$Genotype, dat$Expression_Status)
proportions <- as.data.frame(prop.table(x, margin = 1))
colnames(proportions) <- c("Cluster", "Sample", "Fraction")
p <- ggplot(proportions, aes(fill = Sample, y = Fraction, x = Cluster)) +
geom_bar(position = "stack", stat = "identity")
p <- p + scale_fill_manual(values=c("blue4","red3"))+ theme_bw() +
theme(axis.text.y = element_text(size=20), axis.text.x=element_text(size=20),
axis.title.x =element_text(size=20), axis.title.y = element_text(size=20),
legend.text = element_text(size=20), legend.title = element_text(size=0),
plot.title = element_text(size = 18, face = "plain", hjust = 0.5)) +
labs(y = lab, x = NULL)
return(p)
}
plotStackedBarByGeno("Ascl1", "Fraction of Ascl1-hi cells (>0.01)")

plotStackedBarByGeno("Neurod1", "Fraction of Neurod1-hi cells (>0.01)")

plotStackedBarByGeno("Pou2f3", "Fraction of Pou2f3-hi cells (>0.01)")

Extended Data Fig. 5e
Violin plots of expression of TFs by Leiden cluster
genes <- c("Ascl1","Neurod1","Pou2f3")
# Create violin plots with Kruskal-Wallis test
plots <- lapply(genes, function(gene) {
p <- VlnPlot(TBO_seurat,
features = gene,
group.by = "leiden_scVI_1.2",
cols = my_colors,
alpha = 0.5) + # smaller dots
ggpubr::stat_compare_means(method = "kruskal.test",
label = "p.format",
label.x = 2,size = 5) +
ggtitle("") +
theme(plot.title = element_text(face = "italic"), legend.position = "none", # Remove legend
axis.title.x = element_blank(),axis.title.y = element_text(size = 20),
axis.text.y = element_text(size = 20), axis.text.x = element_text(size = 14)) + # Remove x-axis label
labs(y = "Expression") # Change y-axis label to "Expression"
return(p)
})
# Arrange plots
patchwork::wrap_plots(plots, ncol = 3)

Ext Data Fig 10
FeaturePlot(TBO_seurat, features = c("Iono_Mouse_Ext1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

FeaturePlot(TBO_seurat, features = c("Iono_Human1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

Ext Data Fig. 10e (violin plots of consensus signatures by SCLC
fate)
plotVlnByPhen("Iono_Mouse_Ext1", yl=c(-0.1, 0.45))

plotVlnByPhen("Iono_Human1", yl=c(-0.1, .75))

Fig 5d
Caris SCLC tumor signatures in basal cells
caris_feat <- c("Caris_A1","Caris_Y1","Caris_N1","Caris_Mixed1","Caris_P1","Caris_TN-1")
library(viridis)
v <- FeaturePlot(TBO_seurat, features = caris_feat, pt.size=0.2, reduction='umap')
v <- lapply(v, `+`, scale_color_viridis(option="rocket", direction=-1))
lapply(v, `+`, NoAxes())
[[1]]
[[2]]
[[3]]
[[4]]
[[5]]
[[6]]






Fig 5d (violin plots of human tumor SCLC scores by SCLC fate)
plotVlnByPhen("Caris_A1", yl=c(-0.1, 0.2))

plotVlnByPhen("Caris_Y1", yl=c(-0.1, 0.2))

plotVlnByPhen("Caris_N1", yl=c(-0.1, 0.3))

plotVlnByPhen("Caris_Mixed1", yl=c(-0.1, 0.15))

plotVlnByPhen("Caris_P1", yl=c(-0.1, 0.25))

plotVlnByPhen("Caris_TN.1", yl=c(-0.1, 0.25))

Fig. 5e
Gene signature scores correlation heatmap
signature_matrix <- FetchData(TBO_seurat, vars = c("Caris_A1", "George_A1", "Liu_A1","Lissa_A1","ASCL1_Targets1",
"Caris_N1","George_N1", "Liu_N1","Lissa_N1", "NEUROD1_Targets1",
"Caris_P1","George_P1", "Liu_P1","POU2F3_Targets1",
"Caris_Y1","George_Y1", "Lissa_Y1", "YAP_Activity1",
"T_Cell_Inflamed_Gay1","MHC_Sig_Gay1",
"NE_Consensus1","Basal_Consensus1","Tuft_Consensus1"))
# Compute Pearson correlation matrix
correlation_matrix <- cor(signature_matrix, method = "pearson")
# Define color scale from -1 to 1
breaks_seq <- seq(-1, 1, length.out = 100) # Ensure scale covers full correlation range
pheatmap::pheatmap(correlation_matrix,
color = scico::scico(100, palette = "berlin"),
display_numbers = FALSE,
breaks = breaks_seq, number_color = "gray80",fontsize_number=6,
main = "Signature correlation in mouse TBO Allografts", cluster_cols = TRUE, cluster_rows=TRUE)

Fig 5g
Inflammatory signatures in basal cells
# Fig 5g feature plot (MHC_Sig_Gay1="Antigen presentation") #
FeaturePlot(TBO_seurat, features = c("MHC_Sig_Gay1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

### NMF3-I signature for Fig. 5g
FeaturePlot(TBO_seurat, features = c("NMF3-I1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

### Gay et al SCLC-I signature for Fig. 5g
FeaturePlot(TBO_seurat, features = c("Gay_SCLC-I1"), pt.size=0.2,
reduction='umap') + viridis::scale_color_viridis(option="rocket",direction=-1) & NoAxes()

Fig 5g (violin plots of inflammation scores by SCLC fate)
plotVlnByPhen("MHC_Sig_Gay1", yl=c(-0.1, 0.8))

plotVlnByPhen("NMF3.I1", yl=c(-0.1, 0.5))

plotVlnByPhen("Gay_SCLC.I1", yl=c(-0.1, 0.3))

Fig 5h (violin plots of therapeutic target gene expression by SCLC
fate)
x_labs <- c("A","A/N","N","At","P","SL","B")
v <- VlnPlot(TBO_seurat, features = c("Dll3", "Ncam1", "Sez6", "Tacstd2"),
group.by=c("Pheno"), cols=pheno_col,alpha=0.05, ncol=4)
v <- lapply(v, `+`, labs(x=NULL, y="Expression"))
v <- lapply(v, `+`, theme(axis.text.x = element_text(angle=90)))
v <- lapply(v, `+`, scale_x_discrete(labels=x_labs))
patchwork::wrap_plots(v, ncol=4)

Ext Data Fig 6a
DimPlot(TBO_seurat, group.by='GenoCT', cols=my_colors, shuffle=TRUE,
reduction='umap', label=FALSE, label.size=6) & NoAxes() + NoLegend()

DimPlot(TBO_seurat, group.by='GenoCT', cols=my_colors, shuffle=TRUE,
reduction='fa', label=FALSE, label.size=6) & NoAxes() + NoLegend()

CellTag analysis in other notebook
LS0tCnRpdGxlOiAiUlBNIFJQTUEgQWxsb3Mgbm90ZWJvb2siCmF1dGhvcjogIkFiYmllIElyZWxhbmQsIERhcnJlbiBUeXNvbiIKZGF0ZTogIjIwMjUtMDYtMjQiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIyBNb2RpZnlpbmcgb3JpZ2luYWwgY29kZQoKT3JpZ2luYWwgZmlsZTogW0ZpZzNfNF82X0V4dEZpZzUtNi0xMF9SUE1fUlBNQV9BbGxvc19DZWxsVGFnLlJdKFByZXByb2Nlc3NpbmdfZm9yX3JlZmVyZW5jZS9SX0NvZGUvRmlnM180XzZfRXh0RmlnNS02LTEwX1JQTV9SUE1BX0FsbG9zX0NlbGxUYWcuUikKClRoaXMgbm90ZWJvb2sgaXMgbW9kaWZpZWQgZnJvbSB0aGUgb3JpZ2luYWwgY29kZSB0byByZW1vdmUgdGhlIHByZXByb2Nlc3Npbmcgc3RlcHMgYW5kIHNob3cgZmlndXJlcyBpbmxpbmUgd2l0aGluIHRoZSBub3RlYm9vay4KClRoZXJlIGlzIGEgW3NlcGFyYXRlIG5vdGVib29rIGZvciB0aGUgQ2VsbFRhZyBhbmFseXNpc10oMDRfUlBNX1JQTUFfQWxsb3NfQ2VsbFRhZ19ub3RlYm9vay5uYi5odG1sKS4gIAoKIyMjIFJlbGF0ZWQgdG86CgotICAgRmlnIDJlLWwKLSAgIEZpZyA1ZC1oCi0gICBFeHRlbmRlZCBEYXRhIEZpZyA1YyxlCi0gICBFeHRlbmRlZCBEYXRhIEZpZyA2YQotICAgRXh0ZW5kZWQgRGF0YSBGaWcgMTBlCgpgYGB7cn0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKHsKICAgIGxpYnJhcnkoU2V1cmF0KQogICAgbGlicmFyeShTZXVyYXRPYmplY3QpCiAgICBsaWJyYXJ5KFN1bW1hcml6ZWRFeHBlcmltZW50KQogICAgbGlicmFyeShnZ3Bsb3QyKQogICAgbGlicmFyeShnZ3B1YnIpCn0pCmBgYAoKIyMjIExvYWQgdGhlIFNldXJhdCBvYmplY3QgYW5kIENlbGxUYWcgY2xvbmVzCgpgYGB7cn0KVEJPX3NldXJhdDwtcmVhZFJEUygiLi4vZGF0YS8wN18yMDI1X1JQTV9SUE1BX1RCT19DZWxsVGFnX1NldXJhdF93U2lnc19GQV9kcHRfZmluYWwucmRzIikKVEJPX3NldXJhdAoKY2xvbmVzIDwtIHJlYWRSRFMoIi4uL2RhdGEvMDVfMjAyNV9SUE1fUlBNQV9UQk9BbGxvX0NlbGxUYWdDbG9uZXNfT25seWNsb25lcy5yZHMiKQpjbG9uZXMKYGBgCgojIyMgTG9hZCBvcmdhbm9pZCBkYXRhIGFzIFNpbmdsZUNlbGxFeHBlcmltZW50CgpgYGB7cn0Kc2NlIDwtIGFzLlNpbmdsZUNlbGxFeHBlcmltZW50KFRCT19zZXVyYXQsIGFzc2F5ID0gIm5vcm0iKQpgYGAKCmBgYHtyfQpwaGVub3R5cGVzIDwtIGFzLmNoYXJhY3Rlcih1bmlxdWUoc2NlQGNvbERhdGFAbGlzdERhdGEkUGhlbm8pKQpwaGVub19wYWlyc19saXN0IDwtIGNvbWJuKHBoZW5vdHlwZXMsIDIsIHNpbXBsaWZ5ID0gRkFMU0UpCmBgYAoKIyMjIERlZmluZSBjb2xvciBwYWxldHRlcwoKYGBge3J9Cm15X2NvbG9ycyA8LSBjKAogICIjRTQxQTFDIiwgIyBzdHJvbmcgcmVkCiAgIiMzNzdFQjgiLCAjIG1lZGl1bSBibHVlCiAgIiM0REFGNEEiLCAjIGdyZWVuCiAgIiM5ODRFQTMiLCAjIHB1cnBsZQogICIjRkY3RjAwIiwgIyBvcmFuZ2UKICAiI0ZGRkYzMyIsICMgeWVsbG93CiAgIiNBNjU2MjgiLCAjIGJyb3duCiAgIiNlNzI5OGEiLCAjIHBpbmsKICAiIzY2NjY2NiIsICMgZ3JleQogICIjNjZDMkE1IiwgIyB0ZWFsCiAgIiNGQzhENjIiLCAjIHNhbG1vbgogICIjOERBMENCIiwgIyBzb2Z0IGJsdWUKICAiI0U3OEFDMyIsICMgc29mdCBwaW5rIChkaWZmZXJlbnQgZnJvbSA4KQogICIjQTZEODU0IiwgIyBsaWdodCBncmVlbiAoYnV0IHllbGxvd2lzaCB0aW50LCBub3QgZ3JlZW4pCiAgIiNGRkQ5MkYiLCAjIGxlbW9uIHllbGxvdwogICIjRTVDNDk0IiwgIyBsaWdodCBicm93bgogICIjQjNCM0IzIiwgIyBsaWdodCBncmV5CiAgIiMxQjlFNzciLCAjIGRlZXAgdGVhbAogICIjRDk1RjAyIiwgIyBkYXJrIG9yYW5nZQogICIjNzU3MEIzIiwgIyBzdHJvbmcgcHVycGxlCiAgIiM2NkE2MUUiICAjIG9saXZlIGdyZWVuIChOT1Qgc2FtZSBncmVlbiBhcyBiZWZvcmUpCikKCmBgYAoKIyMjIyBEZWZpbmUgZnVuY3Rpb24gdG8gcGxvdCB2aW9saW4gcGxvdHMgYnkgcGhlbm90eXBlCgpDb3BpZWQgZnJvbSBbMDJfV1RfUlBNX09yZ2Fub2lkc19BbGxvZ3JhZnRzX25vdGVib29rLlJtZF0oMDJfV1RfUlBNX09yZ2Fub2lkc19BbGxvZ3JhZnRzX25vdGVib29rLlJtZCkKCk5lZWRzIFNpbmdsZUNlbGxFeHBlcmltZW50IGBzY2VgIG9iamVjdCBhbmQgYHBoZW5vX3BhaXJzX2xpc3RgIGRlZmluZWQgaW4gdGhlIG5vdGVib29rLgoKYGBge3J9CnBsb3RWbG5CeVBoZW4gPC0gZnVuY3Rpb24oZmVhdHVyZSwgeWw9YygtMC4xLDAuMyksIGZvY3VzPU5BKSB7CiAgICBpZighaXMubmEoZm9jdXMpKSB7CiAgICAgICAgcGhlbm9fcGFpcnNfbGlzdCA8LSBwaGVub19wYWlyc19saXN0W3NhcHBseShwaGVub19wYWlyc19saXN0LCBmdW5jdGlvbih4KSBmb2N1cyAlaW4lIHgpXQogICAgfQogICAgCiAgICBzY2F0ZXI6OnBsb3RDb2xEYXRhKHNjZSwgeCA9ICJQaGVubyIsIHkgPSBmZWF0dXJlLCBjb2xvdXJfYnkgPSAiUGhlbm8iKSArIAogICAgICAgIHNjYWxlX2Rpc2NyZXRlX21hbnVhbChhZXN0aGV0aWNzID0gYygiY29sb3VyIiwgImZpbGwiKSwgdmFsdWVzPXBoZW5vX2NvbCkgKwogICAgICAgIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjQpLCBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYpLAogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLCAgICMgcm90YXRlIHgtYXhpcyBsYWJlbHMKICAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgICAjIHJlbW92ZSBwbG90IHRpdGxlCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiICAgICAgICAgIyByZW1vdmUgbGVnZW5kCiAgICAgICAgKSArIGxhYnMoeCA9ICIiLCAgICAgICAgICAgICAgICAgICAgICMgY3VzdG9tIHgtYXhpcyB0aXRsZQogICAgICAgICAgICAgICAgIHkgPSAiU2lnbmF0dXJlIHNjb3JlIiAgICAgICAgIyBjdXN0b20geS1heGlzIHRpdGxlCiAgICAgICAgKSArIHlsaW0oeWxbMV0sIHlsWzJdKSArIAogICAgICAgIGdlb21fYm94cGxvdChmaWxsPXBoZW5vX2NvbCwgYWxwaGE9MS81LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gLjIpLAogICAgICAgICAgICAgICAgICAgICBzaXplPTAuMiwgY29sb3I9ImJsYWNrIiwgbm90Y2g9VFJVRSwgbm90Y2h3aWR0aD0wLjMsIG91dGxpZXIuc2hhcGUgPSAyLCBvdXRsaWVyLmNvbG91cj1OQSkgIyArIAogICAgICAgICMgc3RhdF9zdW1tYXJ5KGZ1biA9IG1lYW4sCiAgICAgICAgIyAgICAgICAgICAgICAgZ2VvbSA9ICJwb2ludCIsCiAgICAgICAgIyAgICAgICAgICAgICAgc2hhcGUgPSAxOCwKICAgICAgICAjICAgICAgICAgICAgICBzaXplID0gMiwKICAgICAgICAjICAgICAgICAgICAgICBjb2xvciA9ICJyZWQiLAogICAgICAgICMgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjUpKSArIAogICAgICAgICMgZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgbGFiZWwgPSAicC5zaWduaWYiLCBzaXplPTQsIAogICAgICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmp1c3QgPSAwLjUsCiAgICAgICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRlLm5zID0gVFJVRSwgY29tcGFyaXNvbnMgPSBwaGVub19wYWlyc19saXN0KQp9CmBgYAoKIyMjIEZpZy4gMmUgVU1BUAoKYGBge3IgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KRGltUGxvdChUQk9fc2V1cmF0LCBncm91cC5ieT0nR2Vub3R5cGUnLCBjb2xzPWMoImRhcmtvcmNoaWQ0Iiwib3JhbmdlIiksCiAgICAgICAgcHQuc2l6ZSA9IDAuMSwKICAgICAgICByZWR1Y3Rpb249J3VtYXAnLCBsYWJlbD1GQUxTRSwgbGFiZWwuc2l6ZT03LCBzaHVmZmxlPVRSVUUpICYgTm9BeGVzKCkKCmBgYAoKIyMjIEZpZy4gMmYgKFVNQVAgYnkgTGVpZGVuIGNsdXN0ZXIpCgpgYGB7ciBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD02LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpEaW1QbG90KFRCT19zZXVyYXQsIGdyb3VwLmJ5PSdsZWlkZW5fc2NWSV8xLjInLCAKICAgICAgICBjb2xzPW15X2NvbG9ycywgcmVkdWN0aW9uPSd1bWFwJywgbGFiZWw9VFJVRSwgbGFiZWwuc2l6ZT01LAogICAgICAgIHB0LnNpemUgPSAwLjEpICYgTm9BeGVzKCkgKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmBgYAoKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTAsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CklkZW50cyhUQk9fc2V1cmF0KSA8LSAnbGVpZGVuX3NjVklfMS4yJwoKeCA8LSB0YWJsZShUQk9fc2V1cmF0QG1ldGEuZGF0YSRHZW5vdHlwZSxJZGVudHMoVEJPX3NldXJhdCkpCnByb3BvcnRpb25zIDwtIGFzLmRhdGEuZnJhbWUoMTAwKnByb3AudGFibGUoeCwgbWFyZ2luID0gMSkpCgpjb2xuYW1lcyhwcm9wb3J0aW9ucykgPC0gYygiU2FtcGxlIiwgIkNsdXN0ZXIiLCAiRnJlcXVlbmN5IikKCiMgZ2dwdWJyOjpnZ2JhcnBsb3QocHJvcG9ydGlvbnMsIHg9IlNhbXBsZSIsIHk9IkZyZXF1ZW5jeSIsIGZpbGwgPSAiU2FtcGxlIiwgZ3JvdXAgPSAiU2FtcGxlIiwKIyAgICAgICAgICAgICAgICAgICB5bGFiID0gIkZyZXF1ZW5jeSAocGVyY2VudCkiLCB4bGFiPSJQaGFzZSIsIHBhbGV0dGUgPWMoImluZGlhbnJlZDMiLCJncmVlbjMiLCJyb3lhbGJsdWU0IikpICsKIyAgICAgdGhlbWVfYncoKSArIGZhY2V0X3dyYXAoZmFjZXRzID0gIkNsdXN0ZXIiLCBzY2FsZXM9ImZyZWVfeSIsIG5jb2wgPTQpICsKIyAgICAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZT02KSkgKyBnZ3B1YnI6OnJvdGF0ZV94X3RleHQoYW5nbGUgPSA0NSkKYGBgCgojIyMjIEZpZyAyZgoKYGBge3IgZmlnLmhlaWdodD0zLjUsIGZpZy53aWR0aD0zLjUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgU3RhY2tlZApwIDwtIGdncGxvdChwcm9wb3J0aW9ucywgYWVzKGZpbGw9Q2x1c3RlciwgeT1GcmVxdWVuY3ksIHg9U2FtcGxlKSkgKyAKICAgIGdlb21fYmFyKHBvc2l0aW9uPSJzdGFjayIsIHN0YXQ9ImlkZW50aXR5IikKCnAgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9bXlfY29sb3JzKSArIHRoZW1lX2J3KCkgKyAKICAgIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MTYpLCAKICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9MTYsIGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xKSwgCiAgICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZT0xNiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplPTE2KSwgCiAgICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArIAogICAgbGFicyh4ID0gTlVMTCwgeSA9ICJTYW1wbGUgY29tcG9zaXRpb24gKCUpIikKYGBgCgojIyMgRmlnLiAyaAoKVU1BUCBjb2xvcmVkIGJ5IFNDTEMgZmF0ZQoKYGBge3IgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBEZWZpbmUgZmF0ZSBjb2xvciB2ZWN0b3IgYW5kIHVzZSB0byBwbG90IGJ5IGNlbGwgc3RhdGUKcGhlbm9fY29sIDwtIGMoImJyb3duMiIsImRhcmtvcmNoaWQ0IiwiZG9kZ2VyYmx1ZSIsIiM2NkE2MUUiLCJvcmFuZ2UiLCJ0dXJxdW9pc2U0IiwidHVycXVvaXNlIikKRGltUGxvdChUQk9fc2V1cmF0LCBncm91cC5ieT0nUGhlbm8nLCBjb2xzPXBoZW5vX2NvbCwgcmVkdWN0aW9uPSd1bWFwJywgbGFiZWw9RkFMU0UsIAogICAgICAgIHNodWZmbGU9VFJVRSwgbGFiZWwuc2l6ZT02KSAmIE5vQXhlcygpCgpgYGAKCiMjIyMgRmlnLiAyaCAoc3RhY2tlZCBiYXJwbG90IGJ5IFBoZW5vKQoKYGBge3IgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KSWRlbnRzKFRCT19zZXVyYXQpIDwtJ1BoZW5vJwoKeCA8LSB0YWJsZShUQk9fc2V1cmF0QG1ldGEuZGF0YSRHZW5vdHlwZSxJZGVudHMoVEJPX3NldXJhdCkpCnByb3BvcnRpb25zIDwtIGFzLmRhdGEuZnJhbWUoMTAwKnByb3AudGFibGUoeCwgbWFyZ2luID0gMSkpCgpjb2xuYW1lcyhwcm9wb3J0aW9ucyk8LWMoIkNsdXN0ZXIiLCAiU2FtcGxlIiwgIkZyZXF1ZW5jeSIpCgpwIDwtIGdncGxvdChwcm9wb3J0aW9ucywgYWVzKGZpbGw9U2FtcGxlLCB5PUZyZXF1ZW5jeSwgeD1DbHVzdGVyKSkgKyAKICAgIGdlb21fYmFyKHBvc2l0aW9uPSJzdGFjayIsIHN0YXQ9ImlkZW50aXR5IikKCnAgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9cGhlbm9fY29sKSArIHRoZW1lX2J3KCkgKyAKICAgIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MjApLCAKICAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPTIwLCBhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHZqdXN0ID0gMC41KSwgCiAgICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZT0yMCksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSwgCiAgICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjApKSArIAogICAgbGFicyh4ID0gTlVMTCkKYGBgCgojIyMjIEZpZy4gMmkgVU1BUAoKTkUgc2NvcmUgKGNvcnJlbGF0aW9uKQoKYGBge3IgZmlnLmhlaWdodD0zLCBmaWcud2lkdGg9My41LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpGZWF0dXJlUGxvdChUQk9fc2V1cmF0LCBmZWF0dXJlcyA9IGMoIk5FX3NwZWFybWFuIiksIHB0LnNpemU9MC4yLAogICAgICAgICAgICByZWR1Y3Rpb249J3VtYXAnKSArIHZpcmlkaXM6OnNjYWxlX2NvbG9yX3ZpcmlkaXMob3B0aW9uPSJyb2NrZXQiLGRpcmVjdGlvbj0tMSkgJiBOb0F4ZXMoKQpgYGAKCiMjIyMgRmlnIDJpICh2aW9saW4gcGxvdHMgb2YgTkUgc2NvcmUgYnkgU0NMQyBmYXRlKQoKYGBge3IgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcGxvdFZsbkJ5UGhlbigiTkVfc3BlYXJtYW4iLCB5bD1jKC0uNywgLjgpKQpgYGAKCiMjIyMgRmlnIDJpICh2aW9saW4gcGxvdHMgb2YgTkUgc2NvcmUgYnkgZ2Vub3R5cGUpCgpgYGB7ciBmaWcuaGVpZ2h0PTMsIGZpZy53aWR0aD0yLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp4IDwtIHNjYXRlcjo6cGxvdENvbERhdGEoc2NlLCB4ID0gIkdlbm90eXBlIiwgeSA9ICJORV9zcGVhcm1hbiIsIGNvbG91cl9ieSA9ICJHZW5vdHlwZSIpICsgCiAgICBzY2FsZV9kaXNjcmV0ZV9tYW51YWwoYWVzdGhldGljcyA9IGMoImNvbG91ciIsICJmaWxsIiksIHZhbHVlcz1jKCJkYXJrb3JjaGlkNCIsIm9yYW5nZSIpKQoKeCA8LSB4ICsgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCksYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2KSwgCiAgICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICAgICAgICAgIyBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgbGFicyh4ID0gIiIsICB5ID0gIlNpZ25hdHVyZSBzY29yZSIpICsgIHlsaW0oLTEsMSkgKyAKICAgIGdlb21fYm94cGxvdChmaWxsPWMoImRhcmtvcmNoaWQ0Iiwib3JhbmdlIiksIGFscGhhPTEvNSwgCiAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IC4yKSwgc2l6ZT0wLjIsCiAgICAgICAgICAgICAgICAgY29sb3I9ImJsYWNrIiwgbm90Y2g9VFJVRSwgbm90Y2h3aWR0aD0wLjMsIG91dGxpZXIuc2hhcGUgPSAyLCBvdXRsaWVyLmNvbG91cj1OQSkKCiMjIFBlcmZvcm0gd2lsY294b24gcmFuay1zdW0gdGVzdCBmb3IgUlBNIHZzIFJQTUEgb24gdGhlIE5FIHNjb3JlIGRhdGEgKEZpZy4gM2kpICMjCnggKyBzdGF0X3N1bW1hcnkoZnVuID0gbWVhbiwKICAgICAgICAgICAgICAgICBnZW9tID0gInBvaW50IiwKICAgICAgICAgICAgICAgICBzaGFwZSA9IDE4LAogICAgICAgICAgICAgICAgIHNpemUgPSAyLAogICAgICAgICAgICAgICAgIGNvbG9yID0gInJlZCIsCiAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSkpICsgCiAgICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLGxhYmVsID0gInAuc2lnbmlmIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRlLm5zID0gVFJVRSxjb21wYXJpc29ucyA9IGxpc3QoYygiUlBNIiwgIlJQTUEiKSkpCgpgYGAKCiMjIyBGaWcuIDJqCgojIyMjIEZpZyAyaiAoVU1BUCBtYXJrZXIgZ2VuZSBleHByZXNzaW9uKQoKRXF1aXZhbGVudCBjb2xvciBzY2hlbWVzOlwKXCogYHZpcmlkaXM6OnNjYWxlX2NvbG9yX3ZpcmlkaXMob3B0aW9uPSJyb2NrZXQiLCBkaXJlY3Rpb249LTEpYFwKXCogYHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvcnM9dmlyaWRpczo6cm9ja2V0KDEwLCBkaXJlY3Rpb249LTEpKWAKCmBgYHtyIGZpZy5oZWlnaHQ9MywgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgVEYgdGFyZ2V0IGdlbmUgc2NvcmVzIGluIFVNQVAKRmVhdHVyZVBsb3QoVEJPX3NldXJhdCwgZmVhdHVyZXMgPSBjKCJBU0NMMV9UYXJnZXRzMSIpLCBwdC5zaXplPTAuMiwgCiAgICAgICAgICAgIHJlZHVjdGlvbj0ndW1hcCcpICsgdmlyaWRpczo6c2NhbGVfY29sb3JfdmlyaWRpcyhvcHRpb249InJvY2tldCIsZGlyZWN0aW9uPS0xKSAmIE5vQXhlcygpCkZlYXR1cmVQbG90KFRCT19zZXVyYXQsIGZlYXR1cmVzID0gYygiTkVVUk9EMV9UYXJnZXRzMSIpLCBwdC5zaXplPTAuMiwKICAgICAgICAgICAgcmVkdWN0aW9uPSd1bWFwJykgKyB2aXJpZGlzOjpzY2FsZV9jb2xvcl92aXJpZGlzKG9wdGlvbj0icm9ja2V0IixkaXJlY3Rpb249LTEpICYgTm9BeGVzKCkKRmVhdHVyZVBsb3QoVEJPX3NldXJhdCwgZmVhdHVyZXMgPSBjKCJBVE9IMV9UYXJnZXRzMSIpLCBwdC5zaXplPTAuMiwKICAgICAgICAgICAgcmVkdWN0aW9uPSd1bWFwJykgKyB2aXJpZGlzOjpzY2FsZV9jb2xvcl92aXJpZGlzKG9wdGlvbj0icm9ja2V0IixkaXJlY3Rpb249LTEpICYgTm9BeGVzKCkKRmVhdHVyZVBsb3QoVEJPX3NldXJhdCwgZmVhdHVyZXMgPSBjKCJQT1UyRjNfVGFyZ2V0czEiKSwgcHQuc2l6ZT0wLjIsCiAgICAgICAgICAgIHJlZHVjdGlvbj0ndW1hcCcpICsgdmlyaWRpczo6c2NhbGVfY29sb3JfdmlyaWRpcyhvcHRpb249InJvY2tldCIsZGlyZWN0aW9uPS0xKSAmIE5vQXhlcygpCkZlYXR1cmVQbG90KFRCT19zZXVyYXQsIGZlYXR1cmVzID0gYygiWUFQX0FjdGl2aXR5MSIpLCBwdC5zaXplPTAuMiwKICAgICAgICAgICAgcmVkdWN0aW9uPSd1bWFwJykgKyB2aXJpZGlzOjpzY2FsZV9jb2xvcl92aXJpZGlzKG9wdGlvbj0icm9ja2V0IixkaXJlY3Rpb249LTEpICYgTm9BeGVzKCkKCmBgYAoKIyMjIFZsblBsb3RzIGJ5IGdlbm90eXBlIHdpdGggd2lsY294b24gcmFuayBzdW0gdGVzdHMKCiMjIyMgRmlnLiAyaiAodmlvbGluIHBsb3RzKQoKYGBge3J9CnBsb3RURnNjb3Jlc1ZsbiA8LSBmdW5jdGlvbihzY29yZV9uYW1lLCB5bD1jKC0uMSwgLjMyKSkgewogICAgYSA8LSBWbG5QbG90KFRCT19zZXVyYXQsCiAgICAgICAgICAgICAgICAgZmVhdHVyZXMgPSBjKHNjb3JlX25hbWUpLAogICAgICAgICAgICAgICAgIGdyb3VwLmJ5ID0gIkdlbm90eXBlIiwKICAgICAgICAgICAgICAgICBjb2xzID0gYygiZGFya29yY2hpZDQiLCAib3JhbmdlIiksCiAgICAgICAgICAgICAgICAgcHQuc2l6ZSA9IDAuMDEsCiAgICAgICAgICAgICAgICAgYWxwaGEgPSAwLjA1LAogICAgICAgICAgICAgICAgIG5jb2wgPSAxKSArIAogICAgICAgIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLAogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAwLjUsIHNpemU9MjApLCAgIyByb3RhdGUgeC1heGlzIGxhYmVscwogICAgICAgICAgICAgICMgcGxvdC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHJlbW92ZSBwbG90IHRpdGxlCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHJlbW92ZSBsZWdlbmQKICAgICAgICApICsgCiAgICAgICAgbGFicyh4ID0gIiIsICAgICAgICAgICAgICMgY3VzdG9tIHgtYXhpcyB0aXRsZQogICAgICAgICAgICAgeSA9ICJFeHByZXNzaW9uIiAgIyBjdXN0b20geS1heGlzIHRpdGxlCiAgICAgICAgKSArIHlsaW0oeWxbMV0sIHlsWzJdKSArIAogICAgICAgIHN0YXRfc3VtbWFyeShmdW4gPSBtZWFuLAogICAgICAgICAgICAgICAgICAgICBnZW9tID0gInBvaW50IiwKICAgICAgICAgICAgICAgICAgICAgc2hhcGUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDIsCiAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gInJlZCIsCiAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpKSArIAogICAgICAgIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIGxhYmVsID0gInAuc2lnbmlmIiwgc2l6ZT04LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRlLm5zID0gVFJVRSwgY29tcGFyaXNvbnMgPSBsaXN0KGMoIlJQTSIsICJSUE1BIikpKQogICAgICAgIAogICAgICAgICMgQWRkIG1lYW4gcG9pbnQgYW5kIGRvIHdpbGNveG9uIHJhbmsgc3VtIHRlc3QgCiAgICByZXR1cm4oYSkKfQpgYGAKCiMjIyMgRmlnIDJqIChpbnNldHMpCgpgYGB7ciBmaWcuaGVpZ2h0PTMsIGZpZy53aWR0aD0zLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwbG90VEZzY29yZXNWbG4oIkFUT0gxX1RhcmdldHMxIikKcGxvdFRGc2NvcmVzVmxuKCJBU0NMMV9UYXJnZXRzMSIsIHlsPWMoLTAuMSwgMC44KSkKcGxvdFRGc2NvcmVzVmxuKCJORVVST0QxX1RhcmdldHMxIikKcGxvdFRGc2NvcmVzVmxuKCJQT1UyRjNfVGFyZ2V0czEiKQpwbG90VEZzY29yZXNWbG4oIllBUF9BY3Rpdml0eTEiLCB5bD1jKC0wLjEsIDEpKQpgYGAKCiMjIyBGaWcuIDJrIChVTUFQIGJ5IGNlbGwgdHlwZSBjb25zZW5zdXMgc2lnbmF0dXJlKQoKYGBge3IgZmlnLmhlaWdodD0zLCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KRmVhdHVyZVBsb3QoVEJPX3NldXJhdCwgZmVhdHVyZXMgPSBjKCJORV9Db25zZW5zdXMxIiksIHB0LnNpemU9MC4yLCAKICAgICAgICAgICAgcmVkdWN0aW9uPSd1bWFwJykgKyB2aXJpZGlzOjpzY2FsZV9jb2xvcl92aXJpZGlzKG9wdGlvbj0icm9ja2V0IixkaXJlY3Rpb249LTEpICYgTm9BeGVzKCkKRmVhdHVyZVBsb3QoVEJPX3NldXJhdCwgZmVhdHVyZXMgPSBjKCJCYXNhbF9Db25zZW5zdXMxIiksIHB0LnNpemU9MC4yLAogICAgICAgICAgICByZWR1Y3Rpb249J3VtYXAnKSArIHZpcmlkaXM6OnNjYWxlX2NvbG9yX3ZpcmlkaXMob3B0aW9uPSJyb2NrZXQiLGRpcmVjdGlvbj0tMSkgJiBOb0F4ZXMoKQpGZWF0dXJlUGxvdChUQk9fc2V1cmF0LCBmZWF0dXJlcyA9IGMoIlR1ZnRfQ29uc2Vuc3VzMSIpLCBwdC5zaXplPTAuMiwKICAgICAgICAgICAgcmVkdWN0aW9uPSd1bWFwJykgKyB2aXJpZGlzOjpzY2FsZV9jb2xvcl92aXJpZGlzKG9wdGlvbj0icm9ja2V0IixkaXJlY3Rpb249LTEpICYgTm9BeGVzKCkKYGBgCgojIyMgRmlnLiAyayAodmlvbGluIHBsb3RzIG9mIGNvbnNlbnN1cyBzaWduYXR1cmVzIGJ5IFNDTEMgZmF0ZSkKCmBgYHtyIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBsb3RWbG5CeVBoZW4oIk5FX0NvbnNlbnN1czEiLCB5bD1jKC0wLjUsIDEuMykpCnBsb3RWbG5CeVBoZW4oIlR1ZnRfQ29uc2Vuc3VzMSIsIHlsPWMoLTAuMjUsIDEpKQpwbG90VmxuQnlQaGVuKCJCYXNhbF9Db25zZW5zdXMxIiwgeWw9YygtMC4xLCAxLjEpKQpgYGAKCiMjIyMgRmlnIDJsICh2aW9saW4gcGxvdHMgb2YgU0NMQyBhcmhjZXR5cGUgc2NvcmVzIGJ5IHBoZW5vdHlwZSkKCmBgYHtyIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBsb3RWbG5CeVBoZW4oIkFfQXJjaGV0eXBlMSIsIHlsPWMoLTAuMDUsIDAuMjcpKQpwbG90VmxuQnlQaGVuKCJBMl9BcmNoZXR5cGUxIiwgeWw9YygtMC4wNSwgMC4yKSkKcGxvdFZsbkJ5UGhlbigiTl9BcmNoZXR5cGUxIiwgeWw9YygwLCAwLjMpKQpwbG90VmxuQnlQaGVuKCJQX0FyY2hldHlwZTEiLCB5bD1jKDAsIDAuMjcpKQpgYGAKCiMjIyMgRXh0IERhdGEgRmlnIDVjCgpgYGB7cn0KcGxvdFN0YWNrZWRCYXJCeUdlbm8gPC0gZnVuY3Rpb24oZ2VuZSwgbGFiKSB7CiAgICBkYXQgPC0gRmV0Y2hEYXRhKFRCT19zZXVyYXQsIHZhcnMgPSBjKGdlbmUsICJHZW5vdHlwZSIpKQogICAgZGF0IDwtIGRhdCAlPiUKICAgICAgbXV0YXRlKEV4cHJlc3Npb25fU3RhdHVzID0gaWZlbHNlKGRhdFssZ2VuZV0gPiAwLjAxLCAiUG9zaXRpdmUiLCAiTmVnYXRpdmUiKSkKICAgIAogICAgeCA8LSB0YWJsZShkYXQkR2Vub3R5cGUsIGRhdCRFeHByZXNzaW9uX1N0YXR1cykKICAgIAogICAgcHJvcG9ydGlvbnMgPC0gYXMuZGF0YS5mcmFtZShwcm9wLnRhYmxlKHgsIG1hcmdpbiA9IDEpKQogICAgY29sbmFtZXMocHJvcG9ydGlvbnMpIDwtIGMoIkNsdXN0ZXIiLCAiU2FtcGxlIiwgIkZyYWN0aW9uIikKCiAgICBwIDwtIGdncGxvdChwcm9wb3J0aW9ucywgYWVzKGZpbGwgPSBTYW1wbGUsIHkgPSBGcmFjdGlvbiwgeCA9IENsdXN0ZXIpKSArIAogICAgICAgIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdCA9ICJpZGVudGl0eSIpCiAgICBwIDwtIHAgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiYmx1ZTQiLCJyZWQzIikpKyB0aGVtZV9idygpICsgCiAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCksIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPTIwKSwgCiAgICAgICAgICAgICAgYXhpcy50aXRsZS54ID1lbGVtZW50X3RleHQoc2l6ZT0yMCksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSwgCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCksIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTApLCAKICAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgZmFjZSA9ICJwbGFpbiIsIGhqdXN0ID0gMC41KSkgKyAKICAgICAgICBsYWJzKHkgPSBsYWIsIHggPSBOVUxMKQogICAgcmV0dXJuKHApCn0KYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD02LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwbG90U3RhY2tlZEJhckJ5R2VubygiQXNjbDEiLCAiRnJhY3Rpb24gb2YgQXNjbDEtaGkgY2VsbHMgKD4wLjAxKSIpCnBsb3RTdGFja2VkQmFyQnlHZW5vKCJOZXVyb2QxIiwgIkZyYWN0aW9uIG9mIE5ldXJvZDEtaGkgY2VsbHMgKD4wLjAxKSIpCnBsb3RTdGFja2VkQmFyQnlHZW5vKCJQb3UyZjMiLCAiRnJhY3Rpb24gb2YgUG91MmYzLWhpIGNlbGxzICg+MC4wMSkiKQpgYGAKCiMjIyBFeHRlbmRlZCBEYXRhIEZpZy4gNWUKClZpb2xpbiBwbG90cyBvZiBleHByZXNzaW9uIG9mIFRGcyBieSBMZWlkZW4gY2x1c3RlcgoKYGBge3IgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MTAsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmdlbmVzIDwtIGMoIkFzY2wxIiwiTmV1cm9kMSIsIlBvdTJmMyIpCgojIENyZWF0ZSB2aW9saW4gcGxvdHMgd2l0aCBLcnVza2FsLVdhbGxpcyB0ZXN0CnBsb3RzIDwtIGxhcHBseShnZW5lcywgZnVuY3Rpb24oZ2VuZSkgewogIHAgPC0gVmxuUGxvdChUQk9fc2V1cmF0LAogICAgICAgICAgICAgICBmZWF0dXJlcyA9IGdlbmUsCiAgICAgICAgICAgICAgIGdyb3VwLmJ5ID0gImxlaWRlbl9zY1ZJXzEuMiIsCiAgICAgICAgICAgICAgIGNvbHMgPSBteV9jb2xvcnMsCiAgICAgICAgICAgICAgIGFscGhhID0gMC41KSArICAjIHNtYWxsZXIgZG90cwogICAgZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gImtydXNrYWwudGVzdCIsIAogICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gInAuZm9ybWF0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwueCA9IDIsc2l6ZSA9IDUpICsKICAgIGdndGl0bGUoIiIpICsKICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJpdGFsaWMiKSwgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAgIyBSZW1vdmUgbGVnZW5kCiAgICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksCiAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpKSArICAjIFJlbW92ZSB4LWF4aXMgbGFiZWwKICAgIGxhYnMoeSA9ICJFeHByZXNzaW9uIikgICMgQ2hhbmdlIHktYXhpcyBsYWJlbCB0byAiRXhwcmVzc2lvbiIKICByZXR1cm4ocCkKfSkKCiMgQXJyYW5nZSBwbG90cwpwYXRjaHdvcms6OndyYXBfcGxvdHMocGxvdHMsIG5jb2wgPSAzKQpgYGAKCiMjIyMgRXh0IERhdGEgRmlnIDEwCgpgYGB7ciBmaWcuaGVpZ2h0PTMsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpGZWF0dXJlUGxvdChUQk9fc2V1cmF0LCBmZWF0dXJlcyA9IGMoIklvbm9fTW91c2VfRXh0MSIpLCBwdC5zaXplPTAuMiwKICAgICAgICAgICAgcmVkdWN0aW9uPSd1bWFwJykgKyB2aXJpZGlzOjpzY2FsZV9jb2xvcl92aXJpZGlzKG9wdGlvbj0icm9ja2V0IixkaXJlY3Rpb249LTEpICYgTm9BeGVzKCkKRmVhdHVyZVBsb3QoVEJPX3NldXJhdCwgZmVhdHVyZXMgPSBjKCJJb25vX0h1bWFuMSIpLCBwdC5zaXplPTAuMiwKICAgICAgICAgICAgcmVkdWN0aW9uPSd1bWFwJykgKyB2aXJpZGlzOjpzY2FsZV9jb2xvcl92aXJpZGlzKG9wdGlvbj0icm9ja2V0IixkaXJlY3Rpb249LTEpICYgTm9BeGVzKCkKYGBgCgojIyMgRXh0IERhdGEgRmlnLiAxMGUgKHZpb2xpbiBwbG90cyBvZiBjb25zZW5zdXMgc2lnbmF0dXJlcyBieSBTQ0xDIGZhdGUpCgpgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD0zLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwbG90VmxuQnlQaGVuKCJJb25vX01vdXNlX0V4dDEiLCB5bD1jKC0wLjEsIDAuNDUpKQpwbG90VmxuQnlQaGVuKCJJb25vX0h1bWFuMSIsIHlsPWMoLTAuMSwgLjc1KSkKYGBgCgojIyMjIEZpZyA1ZAoKQ2FyaXMgU0NMQyB0dW1vciBzaWduYXR1cmVzIGluIGJhc2FsIGNlbGxzCgpgYGB7ciBmaWcuaGVpZ2h0PTMsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpjYXJpc19mZWF0IDwtICBjKCJDYXJpc19BMSIsIkNhcmlzX1kxIiwiQ2FyaXNfTjEiLCJDYXJpc19NaXhlZDEiLCJDYXJpc19QMSIsIkNhcmlzX1ROLTEiKQpsaWJyYXJ5KHZpcmlkaXMpCnYgPC0gRmVhdHVyZVBsb3QoVEJPX3NldXJhdCwgZmVhdHVyZXMgPSBjYXJpc19mZWF0LCBwdC5zaXplPTAuMiwgcmVkdWN0aW9uPSd1bWFwJykgCnYgPC0gbGFwcGx5KHYsIGArYCwgc2NhbGVfY29sb3JfdmlyaWRpcyhvcHRpb249InJvY2tldCIsIGRpcmVjdGlvbj0tMSkpCmxhcHBseSh2LCBgK2AsIE5vQXhlcygpKQpgYGAKCiMjIyMgRmlnIDVkICh2aW9saW4gcGxvdHMgb2YgaHVtYW4gdHVtb3IgU0NMQyBzY29yZXMgYnkgU0NMQyBmYXRlKQoKYGBge3IgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9My41LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwbG90VmxuQnlQaGVuKCJDYXJpc19BMSIsIHlsPWMoLTAuMSwgMC4yKSkKcGxvdFZsbkJ5UGhlbigiQ2FyaXNfWTEiLCB5bD1jKC0wLjEsIDAuMikpCnBsb3RWbG5CeVBoZW4oIkNhcmlzX04xIiwgeWw9YygtMC4xLCAwLjMpKQpwbG90VmxuQnlQaGVuKCJDYXJpc19NaXhlZDEiLCB5bD1jKC0wLjEsIDAuMTUpKQpwbG90VmxuQnlQaGVuKCJDYXJpc19QMSIsIHlsPWMoLTAuMSwgMC4yNSkpCnBsb3RWbG5CeVBoZW4oIkNhcmlzX1ROLjEiLCB5bD1jKC0wLjEsIDAuMjUpKQpgYGAKCiMjIyMgRmlnLiA1ZQoKR2VuZSBzaWduYXR1cmUgc2NvcmVzIGNvcnJlbGF0aW9uIGhlYXRtYXAKCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTl9CnNpZ25hdHVyZV9tYXRyaXggPC0gRmV0Y2hEYXRhKFRCT19zZXVyYXQsIHZhcnMgPSBjKCJDYXJpc19BMSIsICJHZW9yZ2VfQTEiLCAiTGl1X0ExIiwiTGlzc2FfQTEiLCJBU0NMMV9UYXJnZXRzMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYXJpc19OMSIsIkdlb3JnZV9OMSIsICJMaXVfTjEiLCJMaXNzYV9OMSIsICJORVVST0QxX1RhcmdldHMxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhcmlzX1AxIiwiR2VvcmdlX1AxIiwgIkxpdV9QMSIsIlBPVTJGM19UYXJnZXRzMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYXJpc19ZMSIsIkdlb3JnZV9ZMSIsICJMaXNzYV9ZMSIsICJZQVBfQWN0aXZpdHkxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRfQ2VsbF9JbmZsYW1lZF9HYXkxIiwiTUhDX1NpZ19HYXkxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FX0NvbnNlbnN1czEiLCJCYXNhbF9Db25zZW5zdXMxIiwiVHVmdF9Db25zZW5zdXMxIikpCgojIENvbXB1dGUgUGVhcnNvbiBjb3JyZWxhdGlvbiBtYXRyaXgKY29ycmVsYXRpb25fbWF0cml4IDwtIGNvcihzaWduYXR1cmVfbWF0cml4LCBtZXRob2QgPSAicGVhcnNvbiIpCgojIERlZmluZSBjb2xvciBzY2FsZSBmcm9tIC0xIHRvIDEKYnJlYWtzX3NlcSA8LSBzZXEoLTEsIDEsIGxlbmd0aC5vdXQgPSAxMDApICAjIEVuc3VyZSBzY2FsZSBjb3ZlcnMgZnVsbCBjb3JyZWxhdGlvbiByYW5nZQoKcGhlYXRtYXA6OnBoZWF0bWFwKGNvcnJlbGF0aW9uX21hdHJpeCwgCiAgICAgICAgIGNvbG9yID0gc2NpY286OnNjaWNvKDEwMCwgcGFsZXR0ZSA9ICJiZXJsaW4iKSwKICAgICAgICAgZGlzcGxheV9udW1iZXJzID0gRkFMU0UsIAogICAgICAgICBicmVha3MgPSBicmVha3Nfc2VxLCBudW1iZXJfY29sb3IgPSAiZ3JheTgwIixmb250c2l6ZV9udW1iZXI9NiwKICAgICAgICAgbWFpbiA9ICJTaWduYXR1cmUgY29ycmVsYXRpb24gaW4gbW91c2UgVEJPIEFsbG9ncmFmdHMiLCBjbHVzdGVyX2NvbHMgPSBUUlVFLCBjbHVzdGVyX3Jvd3M9VFJVRSkKYGBgCgojIyMjIEZpZyA1ZwoKSW5mbGFtbWF0b3J5IHNpZ25hdHVyZXMgaW4gYmFzYWwgY2VsbHMKCmBgYHtyIGZpZy5oZWlnaHQ9MywgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgRmlnIDVnIGZlYXR1cmUgcGxvdCAoTUhDX1NpZ19HYXkxPSJBbnRpZ2VuIHByZXNlbnRhdGlvbiIpICMKRmVhdHVyZVBsb3QoVEJPX3NldXJhdCwgZmVhdHVyZXMgPSBjKCJNSENfU2lnX0dheTEiKSwgcHQuc2l6ZT0wLjIsIAogICAgICAgICAgICByZWR1Y3Rpb249J3VtYXAnKSArIHZpcmlkaXM6OnNjYWxlX2NvbG9yX3ZpcmlkaXMob3B0aW9uPSJyb2NrZXQiLGRpcmVjdGlvbj0tMSkgJiBOb0F4ZXMoKQoKIyMjIE5NRjMtSSBzaWduYXR1cmUgZm9yIEZpZy4gNWcKRmVhdHVyZVBsb3QoVEJPX3NldXJhdCwgZmVhdHVyZXMgPSBjKCJOTUYzLUkxIiksIHB0LnNpemU9MC4yLCAKICAgICAgICAgICAgcmVkdWN0aW9uPSd1bWFwJykgKyB2aXJpZGlzOjpzY2FsZV9jb2xvcl92aXJpZGlzKG9wdGlvbj0icm9ja2V0IixkaXJlY3Rpb249LTEpICYgTm9BeGVzKCkKCiMjIyBHYXkgZXQgYWwgU0NMQy1JIHNpZ25hdHVyZSBmb3IgRmlnLiA1ZwpGZWF0dXJlUGxvdChUQk9fc2V1cmF0LCBmZWF0dXJlcyA9IGMoIkdheV9TQ0xDLUkxIiksIHB0LnNpemU9MC4yLCAKICAgICAgICAgICAgcmVkdWN0aW9uPSd1bWFwJykgKyB2aXJpZGlzOjpzY2FsZV9jb2xvcl92aXJpZGlzKG9wdGlvbj0icm9ja2V0IixkaXJlY3Rpb249LTEpICYgTm9BeGVzKCkKCmBgYAoKIyMjIyBGaWcgNWcgKHZpb2xpbiBwbG90cyBvZiBpbmZsYW1tYXRpb24gc2NvcmVzIGJ5IFNDTEMgZmF0ZSkKCmBgYHtyIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTMuNSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcGxvdFZsbkJ5UGhlbigiTUhDX1NpZ19HYXkxIiwgeWw9YygtMC4xLCAwLjgpKQpwbG90VmxuQnlQaGVuKCJOTUYzLkkxIiwgeWw9YygtMC4xLCAwLjUpKQpwbG90VmxuQnlQaGVuKCJHYXlfU0NMQy5JMSIsIHlsPWMoLTAuMSwgMC4zKSkKYGBgCgojIyMjIEZpZyA1aCAodmlvbGluIHBsb3RzIG9mIHRoZXJhcGV1dGljIHRhcmdldCBnZW5lIGV4cHJlc3Npb24gYnkgU0NMQyBmYXRlKQoKYGBge3IgZmlnLmhlaWdodD0yLjUsIGZpZy53aWR0aD04fQp4X2xhYnMgPC0gYygiQSIsIkEvTiIsIk4iLCJBdCIsIlAiLCJTTCIsIkIiKQoKdiA8LSBWbG5QbG90KFRCT19zZXVyYXQsIGZlYXR1cmVzID0gYygiRGxsMyIsICJOY2FtMSIsICJTZXo2IiwgIlRhY3N0ZDIiKSwgCiAgICAgICAgZ3JvdXAuYnk9YygiUGhlbm8iKSwgY29scz1waGVub19jb2wsYWxwaGE9MC4wNSwgbmNvbD00KQp2IDwtIGxhcHBseSh2LCAgYCtgLCBsYWJzKHg9TlVMTCwgeT0iRXhwcmVzc2lvbiIpKQp2IDwtIGxhcHBseSh2LCAgYCtgLCB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT05MCkpKQp2IDwtIGxhcHBseSh2LCAgYCtgLCAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9eF9sYWJzKSkKCnBhdGNod29yazo6d3JhcF9wbG90cyh2LCBuY29sPTQpCmBgYAoKIyMjIyBFeHQgRGF0YSBGaWcgNmEKCmBgYHtyIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTV9CkRpbVBsb3QoVEJPX3NldXJhdCwgZ3JvdXAuYnk9J0dlbm9DVCcsIGNvbHM9bXlfY29sb3JzLCBzaHVmZmxlPVRSVUUsIAogICAgICAgIHJlZHVjdGlvbj0ndW1hcCcsIGxhYmVsPUZBTFNFLCBsYWJlbC5zaXplPTYpICYgTm9BeGVzKCkgKyBOb0xlZ2VuZCgpCkRpbVBsb3QoVEJPX3NldXJhdCwgZ3JvdXAuYnk9J0dlbm9DVCcsIGNvbHM9bXlfY29sb3JzLCBzaHVmZmxlPVRSVUUsIAogICAgICAgIHJlZHVjdGlvbj0nZmEnLCBsYWJlbD1GQUxTRSwgbGFiZWwuc2l6ZT02KSAmIE5vQXhlcygpICsgTm9MZWdlbmQoKQpgYGAKCiMjIyBDZWxsVGFnIGFuYWx5c2lzIGluIG90aGVyIG5vdGVib29rCg==